﻿using client;
using ConfClient;
using System.IO;
using gpb = global::Google.Protobuf;

namespace SvCore.Tcp;


public partial class MyPackage
{
    public uint ProtocolId { get; set; }
    public short Ecode { get; set; }
    public byte[] Body { get; set; }

    public EProtocolResult ECode => (EProtocolResult)Ecode;

    public static MyPackage From<T>(T msg, EProtocolResult ecode = EProtocolResult.成功) where T : gpb.IMessage
    {
        var pack = new MyPackage();
        pack.ProtocolId = CoreHash.HashMsg<T>();
        pack.Ecode = (short)ecode;

        MemoryStream msgStream = new MemoryStream();
        gpb::CodedOutputStream outputStream = new gpb::CodedOutputStream(msgStream);
        msg.WriteTo(outputStream);
        outputStream.Flush();
        pack.Body = msgStream.ToArray();

        return pack;
    }
    public byte[] Encode()
    {
        var DataSize = 4 + 2 + Body.Length;
        var Data = new byte[4 + DataSize];
        
        Data[0] = (byte)(DataSize & 0xff);
        Data[1] = (byte)((DataSize & 0xff00) >> 8);
        Data[2] = (byte)((DataSize & 0xff0000) >> 16);
        Data[3] = (byte)((DataSize & 0xff000000) >> 24);

        Data[4] = (byte)(ProtocolId & 0xff);
        Data[5] = (byte)((ProtocolId & 0xff00) >> 8);
        Data[6] = (byte)((ProtocolId & 0xff0000) >> 16);
        Data[7] = (byte)((ProtocolId & 0xff000000) >> 24);

        Data[8] = (byte)(Ecode & 0xff);
        Data[9] = (byte)((Ecode & 0xff00) >> 8);

        int index = 4 + 4 + 2;
        while (index < 4 + DataSize)
        {
            Data[index] = Body[index - (4 + 4 + 2)];
            index++;
        }

        return Data;
    }
    public T GetMsg<T>() where T : gpb::IMessage<T>, new()
    {
        var t = new T();
        t.MergeFrom(new gpb::CodedInputStream(Body));
        return t;
    }
    public void GetMsg<T>(out T t) where T : gpb::IMessage<T>, new()
    {
        t = new T();
        t.MergeFrom(new gpb::CodedInputStream(Body));
    }
}
